// 扩展vue原有的功能: 全局组件、自定义指令、挂载原型方法， 注意：没有全局过滤器
// 这就是插件
// vue2.0插件写法要素：导出一个对象，有install函数，默认传入默认传入Vue构造函数，vue基础之上扩展
// vue3.0插件写法要素： 导出一个对象，有install函数，默认传入默认传入App实例，app基础之上扩展

// import XtxSkeleton from './xtx-skeleton'
// import XtxCarousel from './xtx-carousel'
// import XtxMore from './xtx-more'
import defaultImg from '@/assets/images/200.png'
// import XtxBread from './xtx-bread'
// import XtxBreadItem from './xtx-bread-item'
import Message from '@/components/library/Message'
import Confirm from '@/components/library/xtx-confirm'
// 批量注册组件
// 1.使用'require'提供的函数 'content'加载某一个目录下的所有的.vue文件
// 2.然后'content'函数会返回一个导入函数`importFn` 有属性keys()  获取所有的文件路径
// 3.通过文件路径数组，通过遍历数组，再使用importFn 根据路径导入组件对象， 遍历同时进行全局注册

// context(目录路径, 是否加载子目录， 加载文件的匹配正则)
const importFn = require.context('./', false, /\.vue$/)
export default {
  install (app) {
    //  在app上进行扩展， app提供component directive函数
    //  如果要挂载原型 app.config.globalProperties方式
    // app.components(XtxSkeleton.name, XtxSkeleton)
    // app.components(XtxCarousel.name, XtxCarousel)
    // app.components(XtxMore.name, XtxMore)
    // app.components(XtxBread.name, XtxBread)
    // app.components(XtxBreadItem.name, XtxBreadItem)

    // 依据keys批量注册
    importFn.keys().forEach(path => {
      // 导入组件
      const component = importFn(path).default
      // console.log(components)
      //  注册组件
      app.component(component.name, component)
    })
    //  定义指令
    defineDirective(app)
    //  定义一个原型函数
    app.config.globalProperties.$message = Message
    app.config.globalProperties.$confirm = Confirm
  }
}

// 定义指令
const defineDirective = (app) => {
  //  1.图片懒加载 v-lazy
  // 原理： 先存储图片地址不能在src上，当图片进入可视区域，将存储的图片地址设置给图片元素即可
  app.directive('lazy', {
    //  vue2.0 监听使用指令的DOM是否创建好,钩子函数inserted
    //  vue3.0 的指令拥有的钩子函数和组件的一样，使用指令的DOM是否创建好， 钩子函数mounted
    mounted (el, binding) {
      //  2.创建一个观察对象，来观察当前使用指令的元素
      const observe = new IntersectionObserver(([{ isIntersecting }]) => {
        if (isIntersecting) {
          // 停止观察
          observe.unobserve(el)
          //  3.把指令的值设置给el的src属性  binding.value就是指令的值
          //  4.处理图片加载失败 onerror图片加载失败事件
          el.onerror = () => {
            //  加载失败，设置默认图片
            el.src = defaultImg
          }
          el.src = binding.value
        }
      }, {
        threshold: 0
      })
      observe.observe(el)
    }
  })
}
